import { Device, GatewayType } from "@/api/interface/iot";
import {
	addDevice,
	changeGroup,
	getDeviceList,
	getDeviceListALl,
	modifyDevice,
	removeDevice,
	saveToProduct,
	syncDevice
} from "@/api/modules/iot/device";
import img17 from "@/assets/images/iot/device/deviceInfo/17.png";
import DialogBox from "@/components/DialogBox";
import Empty from "@/components/Empty";
import BaseMap from "@/components/Map/antvl7/BaseMap";
import ProTable from "@/components/ProTable/index.vue";
import { ColumnProps } from "@/components/ProTable/interface";
import DeptTree from "@/components/Sansan/DeptTree";
import SelectDeptList from "@/components/Sansan/SelectDeptList";
import SelectGagewayList from "@/components/Sansan/SelectGagewayList";
import OnlineStatus from "@/components/Sansan/Status/OnlineStatus";
import BaseSearchForm from "@/components/SearchForm/BaseSearchForm";
import tableList from "@/components/TableList/index";
import { MessageType } from "@/enums/messageEnum";
import { RouterPath } from "@/enums/routerPath";
import { DeviceStatusEnum } from "@/enums/statusEnum";
import { useAddress } from "@/hooks/useAddress";
import { useAuthButtons } from "@/hooks/useAuthButtons";
import { AuthBtns, deptAnonymous } from "@/utils/constants";
import { dataFormat } from "@/utils/format";
import { confirm, showMsg, showTips } from "@/utils/util";
import { gotoPage } from "../../../utils/routerUtil";
import SaveToProduct from "../product/components/SaveToProduct";
import BasicDialog from "./components/basicInfo/basicDialog";
import "./css/device-list.scss";
import { getProductList } from "@/api/modules/iot/product";
import { ComponentInternalInstance, getCurrentInstance } from "vue";
export default defineComponent({
	name: "DeviceList",
	components: {
		tableList
	},
	setup() {
		const { proxy } = getCurrentInstance() as ComponentInternalInstance;
		const proTable = ref();
		let status = reactive<any>({
			gatewayMap: {} as { [key: string]: Device.ResGateway },
			productMap: {} as { [key: string]: Device.ResProduct },
			columns: [
				{ type: "selection", fixed: "left", width: "auto" },
				{ label: proxy?.$t("device.tablist_label.onlineStatus"), prop: "onlineStatus", width: 80, search: { slot: {} } },
				{ label: proxy?.$t("device.tablist_label.name"), prop: "name", width: 180, search: { slot: {} } },
				{ label: proxy?.$t("device.tablist_label.sn"), prop: "sn", width: 200, search: { slot: {} } },
				{ label: proxy?.$t("device.tablist_label.gatewaySn"), prop: "gatewaySn", width: 200, search: { slot: {} } },
				{ label: proxy?.$t("device.tablist_label.deptName"), prop: "deptName", width: 130, search: { slot: {} } },
				{ label: proxy?.$t("device.tablist_label.lastLiveTime"), prop: "lastLiveTime", sortable: true, width: 170 },
				{ label: proxy?.$t("device.tablist_label.productModel"), prop: "productModel", search: { el: "input" } },
				{ label: proxy?.$t("device.tablist_label.location"), prop: "location" },
				{ label: proxy?.$t("device.tablist_label.operate"), fixed: "right", prop: "operate", width: 130 }
			] as ColumnProps[],
			tableData: [],
			tableMode: "list",
			setting: {
				titleIcon: img17, // 图标
				titleKey: "name", // 标题字段
				subtitleKey: "sn", // 副标题字段
				subtitleName: "设备序列号：",
				selection: true // 是否复选框
			}
		});

		const collapsedSearch = ref<boolean>(false);
		const initParam = reactive<Device.ReqDeviceParam>({});
		const dataCallback = (data: any) => {
			return {
				datalist: data.records,
				total: data.total || 0,
				pageIndex: data.current,
				pageSize: data.size
			};
		};

		const getTableList = async (params: any) => {
			return getDeviceList({ ...params, deptIdNot: deptAnonymous });
		};
		const buttonsList = ref<any>([]);
		onMounted(async () => {
			// 获取页面按钮权限
			useAuthButtons().then(btnList => {
				buttonsList.value = btnList.filter((item: any) => !item.btnGroup || item.btnGroup != 3);
			});

			getProductList({ pageIndex: 1, pageSize: 9999, deviceType: GatewayType.Device }).then(res => {
				let prodList = res.result?.records || [];
				prodList.forEach((item: Device.ReqProduct) => {
					status.productMap[item.model] = item;
				});
			});
		});
		onActivated(() => {
			proTable.value.getTableList();
		});
		//按钮事件
		const clickBtn = function (fn: String, scope?: any) {
			let selectList = scope?.row ? [scope?.row] : scope?.selectList || [];
			switch (fn) {
				case "assignGroup":
					if (!selectList.length) {
						showMsg(proxy?.$t("device.btnmsg.assignGroup"), MessageType.warning);
						return;
					}
					assignGroupDialog.detail.selectList = selectList;
					assignGroupDialog.visible = true;
					break;
				case "strangeGroup":
					if (!selectList.length) {
						showMsg(proxy?.$t("device.btnmsg.strangeGroup"), MessageType.warning);
						return;
					}
					assignGroupDialog.detail.selectList = selectList;
					submitAssignGroup(deptAnonymous);
					break;
				case "updateLocation":
					if (selectList.length != 1) {
						showMsg(proxy?.$t("device.btnmsg.updateLocation"), MessageType.warning);
						return;
					}
					updateLocationDialog.detail = { ...(selectList[0] || {}) };
					updateLocationDialog.visible = true;
					break;
				case "mod":
					if (selectList.length != 1) {
						showMsg(proxy?.$t("device.btnmsg.mod"), MessageType.warning);
						return;
					}
					addDeviceDialog.visible = true;
					addDeviceDialog.detail = selectList[0];
					break;
				case "details":
					gotoPage(RouterPath.deviceDetail, { sn: selectList[0].sn });
					break;
				case "del":
					if (!selectList.length) {
						showMsg(proxy?.$t("device.btnmsg.del"), MessageType.warning);
						return;
					}
					confirm({ content: proxy?.$t("device.btnmsg_content.del") }).then(flag => {
						flag && delDevice(selectList.map((item: any) => item.id).join(","));
					});
					break;
				case "add":
					addDeviceDialog.detail = { location: {}, type: GatewayType.Device };
					addDeviceDialog.visible = true;
					break;
				case "saveToProduct":
					if (selectList.length != 1) {
						showMsg(proxy?.$t("device.btnmsg.saveToProduct"), MessageType.warning);
						return;
					}
					saveToProductDialog.formData.id = selectList[0].sn;
					saveToProductDialog.formData.name = selectList[0].name;
					saveToProductDialog.visible = true;
					break;
				case "sync":
					syncDevice({ idSn: selectList.map((item: any) => item.sn).join(",") }).then(res => {
						showTips(res.code, proxy?.$t("device.tips.sync"), res.message);
					});
					break;
			}
		};
		//删除设备
		const delDevice = async (id: string) => {
			let { code, message } = await removeDevice({ idSn: id });
			let ok = showTips(code, proxy?.$t("device.tips.del_device"), message);
			if (ok) {
				proTable.value.clearSelection();
				proTable.value.reset();
			}
		};
		// let detail = reactive<any>({ location: {}, type: GatewayType.Device });
		const addDeviceDialog = reactive<any>({
			title: proxy?.$t("device.dialog_title.add_device"),
			visible: false,
			detail: {}
		});
		//新增设备
		const submitAdd = async () => {
			addDeviceDialog.detail.name = addDeviceDialog.detail.name || addDeviceDialog.detail.sn;
			let api = addDeviceDialog.detail.id ? modifyDevice : addDevice;
			let { code, message } = await api(addDeviceDialog.detail);
			let ok = showTips(
				code,
				addDeviceDialog.detail.id ? proxy?.$t("device.tips.edit_device") : proxy?.$t("device.tips.add_device"),
				message
			);
			if (ok) {
				addDeviceDialog.visible = false;
				proTable.value.clearSelection();
				proTable.value.getTableList();
			}
		};

		const assignGroupDialog = reactive<any>({
			visible: false,
			title: proxy?.$t("device.dialog_title.assign_group"),
			detail: {
				selectList: [],
				deptId: "",
				deptName: ""
			}
		});

		//调整分组
		const submitAssignGroup = async (groupId?: string) => {
			let { code, message } = await changeGroup({
				idSn: assignGroupDialog.detail.selectList.map((item: any) => item.id).toString(),
				deptId: groupId || assignGroupDialog.detail.deptId
			});
			let ok = showTips(code, proxy?.$t("device.tips.assign_group"), message);
			if (ok) {
				assignGroupDialog.visible = false;
				proTable.value.getTableList();
			}
		};
		const { updateLocationDialog, submitLocation } = useAddress(modifyDevice, proTable);

		const saveToProductDialog = reactive<any>({
			visible: false,
			formData: {
				id: "",
				name: "",
				type: GatewayType.Device
			}
		});

		const submitToProduct = async (data: Device.ReqProduct) => {
			data.idSn = data.id;
			let { code, message } = await saveToProduct(data);
			let ok = showTips(code, proxy?.$t("device.tips.save_to_product"), message);
			if (ok) saveToProductDialog.visible = false;
		};
		const handleChange = (e: any) => {
			if (e.prop == "lastLiveTime") {
				initParam.sortField = "last_live_time";
				initParam.sortOrder = e.order == "ascending" ? "asc" : e.order == "descending" ? "desc" : "";
				proTable.value.getTableList();
			}
		};
		return () => {
			return (
				<div class="deviceInfo-module">
					<SaveToProduct
						title={proxy?.$t("device.dialog_title.save_to_product")}
						v-model:visible={saveToProductDialog.visible}
						formData={saveToProductDialog.formData}
						width="600px"
						onSubmit={(data: Device.ReqProduct) => {
							submitToProduct(data);
						}}
					/>
					<DialogBox
						class="dialog-dense"
						title={assignGroupDialog.title}
						v-model:visible={assignGroupDialog.visible}
						width="500px"
					>
						<DeptTree detail={assignGroupDialog.detail} onChange={() => submitAssignGroup()} class="p-8 assign-group" />
					</DialogBox>
					<DialogBox
						class="dialog-dense"
						title={updateLocationDialog.title}
						v-model:visible={updateLocationDialog.visible}
						onConfirm={() => submitLocation()}
					>
						{updateLocationDialog.visible ? (
							<BaseMap style="height:50vh" editerMarker detail={updateLocationDialog.detail} />
						) : null}
						<div class="address-detail">{updateLocationDialog.detail.location?.address}</div>
					</DialogBox>
					<BasicDialog
						title={addDeviceDialog.detail.id ? proxy?.$t("device.basic_dialog_title.edit_device") : addDeviceDialog.title}
						v-model:visible={addDeviceDialog.visible}
						detail={addDeviceDialog.detail}
						onSubmit={() => submitAdd()}
					/>

					{collapsedSearch.value ? null : (
						<BaseSearchForm class="mb-2">
							<el-form
								class="flex pt-4 pl-4 pr-4 bg-white"
								style="flex-wrap: wrap;"
								onKeyup={(e: KeyboardEvent) => (e.keyCode == 13 ? proTable.value.getTableList() : null)}
							>
								<el-form-item class="search-item" label={proxy?.$t("device.search_label.deptName")}>
									<div style="width:180px">
										<SelectDeptList detail={initParam} appendChild />
									</div>
								</el-form-item>
								<el-form-item class="search-item" label={proxy?.$t("device.search_label.gatewaySn")}>
									<div style="width:180px">
										<SelectGagewayList gatewayMap={status.gatewayMap} detail={initParam} />
									</div>
								</el-form-item>
								<el-form-item class="search-item" label={proxy?.$t("device.search_label.name")}>
									<el-input
										v-model={initParam.name}
										placeholder={proxy?.$t("device.search_placeholder.name")}
										style="width:130px"
									/>
								</el-form-item>
								<el-form-item class="search-item" label={proxy?.$t("device.search_label.sn")}>
									<el-input v-model={initParam.sn} placeholder={proxy?.$t("device.search_placeholder.sn")} style="width:130px" />
								</el-form-item>
								<el-form-item class="search-item" label={proxy?.$t("device.search_label.productModel")}>
									<el-input
										v-model={initParam.productModel}
										placeholder={proxy?.$t("device.search_placeholder.productModel")}
										style="width:130px"
									/>
								</el-form-item>
								<el-form-item class="search-item" label={proxy?.$t("device.search_label.onlineStatus")}>
									<el-select v-model={initParam.onlineStatus} style="width:100px">
										<el-option label={proxy?.$t("device.status_option.all")} value=""></el-option>
										<el-option label={proxy?.$t("device.status_option.online")} value={DeviceStatusEnum.ONLINE}></el-option>
										<el-option label={proxy?.$t("device.status_option.offline")} value={DeviceStatusEnum.OFFLINE}></el-option>
									</el-select>
								</el-form-item>
								<el-form-item class="search-item">
									<el-button type="primary" class="iconfont iconsearch" onClick={() => proTable.value.getTableList()}>
										{proxy?.$t("common.btn.search")}
									</el-button>
									<el-button
										class="iconfont iconsearch"
										onClick={() => {
											for (let key in initParam) {
												initParam[key] = null;
											}
											// proTable.value.getTableList();
										}}
									>
										{proxy?.$t("common.btn.reset")}
									</el-button>
								</el-form-item>
							</el-form>
						</BaseSearchForm>
					)}
					<ProTable
						ref={proTable}
						title={buttonsList.value.length ? "" : proxy?.$t("device.tabtitle.equipment_manage")}
						custSearch
						onSearchCollapsed={val => {
							collapsedSearch.value = val;
						}}
						ignoreInit
						columns={status.columns}
						requestApi={getTableList}
						initParam={initParam}
						dataCallback={dataCallback}
						onSortChange={handleChange}
					>
						{{
							tableHeader: (scope: any) => {
								return buttonsList.value?.map((item: any) => {
									return (
										<el-button onClick={() => clickBtn(item.path, scope)} type={item.btnClass}>
											<i class={`iconfont ${item.icon}`}></i>
											{item.menuName}
										</el-button>
									);
								});
							},
							sn: (scope: any) => {
								return (
									<div
										title={proxy?.$t("device.tiptitle.detail")}
										class="truncate cursor-pointer primary-color"
										onClick={() => gotoPage(RouterPath.deviceDetail, { sn: scope.row.sn })}
									>
										{scope.row.sn}
									</div>
								);
							},
							gatewaySn: (scope: any) => {
								return scope.row.gatewaySn ? (
									<div
										title={proxy?.$t("device.tiptitle.gatewaySn")}
										class="truncate cursor-pointer primary-color"
										onClick={async () => {
											let { result } = await getDeviceListALl({ sn: scope.row.gatewaySn, pageIndex: 1, pageSize: 1 });
											if (result.records.length > 0) {
												let obj = {
													sn: scope.row.gatewaySn,
													type: result.records[0].type,
													menuId: ""
												};
												switch (result.records[0].productModel) {
													case "SS10A":
														obj.menuId = AuthBtns.ss10Gateway;
														break;
													case "SS30S":
														obj.menuId = AuthBtns.ss30Gateway;
														break;
													default:
														obj.menuId = AuthBtns.softGateway;
												}
												gotoPage(RouterPath.gatewayDetail, obj);
											}
										}}
									>
										{status.gatewayMap?.[scope.row.gatewaySn]?.name || scope.row.gatewaySn}
									</div>
								) : (
									"--"
								);
							},
							productModel: (scope: any) => {
								return scope.row.productModel ? (
									<div
										title={proxy?.$t("device.tiptitle.productModel")}
										class="truncate cursor-pointer primary-color"
										onClick={() => gotoPage(RouterPath.productDetail, { productModel: scope.row.productModel })}
									>
										{status.productMap?.[scope.row.productModel]?.name || scope.row.productModel}
									</div>
								) : (
									"--"
								);
							},
							location: (scope: any) => {
								return (
									<div
										title={proxy?.$t("device.tiptitle.location")}
										class="truncate cursor-pointer primary-color"
										onClick={() => clickBtn("updateLocation", scope)}
									>
										{scope.row.location?.address || "--"}
									</div>
								);
							},
							logoutTime: (scope: any) => {
								return dataFormat("datetime", scope.row.logoutTime);
							},
							lastLiveTime: (scope: any) => {
								return dataFormat("datetime", scope.row.lastLiveTime);
							},
							onlineStatus: (scope: any) => {
								return <OnlineStatus v-model={scope.row.onlineStatus} />;
							},
							operate: (scope: any) => {
								return (
									<>
										{buttonsList.value
											.filter((item: any) => item.path == "del")
											.map((item: any) => {
												return (
													<el-popconfirm
														title={proxy?.$t("device.confirm_title.delete")}
														popper-class="jsonform-tooltip"
														onConfirm={() => delDevice(scope.row.id)}
													>
														{{
															reference: () => {
																return (
																	<el-link type="danger">
																		<i class="iconfont icontrash-2"></i>
																		{item.menuName}
																	</el-link>
																);
															}
														}}
													</el-popconfirm>
												);
											})}
										{!buttonsList.value.find((item: any) => item.path == "del") ? (
											<el-link type="danger" disabled>
												<i class="iconfont icontrash-2"></i>
												{proxy?.$t("device.operate.delete")}
											</el-link>
										) : null}
										<el-link type="primary" link class="iconfont iconbx-file" onClick={() => clickBtn("details", scope)}>
											{proxy?.$t("device.operate.detail")}
										</el-link>
									</>
								);
							},
							empty: () => {
								return (
									<div>
										<Empty
											class="text-left leading-6"
											subtitle={proxy?.$t("device.empty.subtitle")}
											btnText={proxy?.$t("device.empty.btntext")}
											onAdd={(scope: any) => clickBtn("add", scope)}
										/>
									</div>
								);
							}
						}}
					</ProTable>
				</div>
			);
		};
	}
});
